package com.ruoyi.websocket.handler;

import cn.hutool.extra.spring.SpringUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.websocket.config.INettyConfig;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import io.netty.util.Attribute;
import io.netty.util.AttributeKey;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;

/**
 * @author xinian
 * @date 2024/12/25
 */
@Slf4j
public class TextHandler extends SimpleChannelInboundHandler<TextWebSocketFrame> {
    private INettyConfig iNettyConfig;
    public TextHandler() {
        iNettyConfig = SpringUtil.getBean(INettyConfig.class);
    }

    public TextHandler(INettyConfig iNettyConfig) {
        this.iNettyConfig = iNettyConfig;
    }
    @Override
    public void handlerAdded(ChannelHandlerContext ctx) {
        IMessageProcessor iMessageProcessor = this.getiMessageProcessor();
        if (iMessageProcessor != null) {
            iMessageProcessor.handlerAdded(ctx);
        }
    }

    /**
     * 客户端订阅的消息处理方法，此处客户端指的是 前端订阅
     */
    @Override
    protected void channelRead0(ChannelHandlerContext ctx, TextWebSocketFrame frame) {
        String request = frame.text();
        IMessageProcessor iMessageProcessor = this.getiMessageProcessor();
        if (iMessageProcessor != null) {
            iMessageProcessor.beforeProcess(ctx,frame);
            if (JSON.isValidObject(request)) {
                iMessageProcessor.processJson(JSONObject.parseObject(request),ctx,frame);
            }else if(JSON.isValidArray(request)){
                iMessageProcessor.processArray(JSONArray.parseArray(request),ctx,frame);
            }else{
                iMessageProcessor.process(ctx,frame);
            }
            iMessageProcessor.afterProcess(ctx,frame);
        }else{
            log.error("没有找到对应的消息处理器");
        }
    }

    private IMessageProcessor getiMessageProcessor() {
        IMessageProcessor iMessageProcessor = null;
        try{
            iMessageProcessor = SpringUtil.getBean(IMessageProcessor.class);
        }catch (NoSuchBeanDefinitionException e){
            log.error("没有找到对应的消息处理器");
        }
        return iMessageProcessor;
    }

    @Override
    public void handlerRemoved(ChannelHandlerContext ctx)  {
        if (iNettyConfig.getEnabledToken()) {
            Attribute<String> token = ctx.channel().attr(AttributeKey.valueOf("TOKEN"));
            IMessageProcessor.allChannel.remove(token.get());
        }else{
            IMessageProcessor.allChannel.remove(ctx.channel().id().asLongText());
        }
        IMessageProcessor iMessageProcessor = this.getiMessageProcessor();
        if (iMessageProcessor != null) {
            log.info("客户端断开连接，并从所有订阅中移除");
            iMessageProcessor.handlerRemoved(ctx);
        }else{
            log.error("没有找到对应的消息处理器");
        }
    }
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        log.error("连接异常:{}",cause.getMessage(),cause);
        IMessageProcessor iMessageProcessor = this.getiMessageProcessor();
        if (iMessageProcessor != null) {
            log.info("客户端断开连接，并从所有订阅中移除");
            iMessageProcessor.handlerRemoved(ctx);
        }else{
            log.error("没有找到对应的消息处理器");
        }
        ctx.close();
    }

}
